﻿package com.vigmonk.net
{
	import com.vigmonk.events.LoaderEvent;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.HTTPStatusEvent;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;
	import flash.utils.ByteArray;
	import flash.utils.Dictionary;		
	
	/**
	 * 
	 * SendAndLoadManager.as
	 * @author VIGMONK
	 * 
	 */
	
	/**
	 * 
	 * import com.vigmonk.events.LoaderEvent;	
	 * import com.vigmonk.net.SendLoadManager;
	 * 
	 * var sendLoader:SendLoadManager = new SendLoadManager();
	 * sendLoader.addEventListener(LoaderEvent.LOAD_COMPLETE,comp);
	 * sendLoader.init();
	 * 
	 * private function comp(_e:LoaderEvent):void
	 * {
	 * 		trace(_e.data.result);
	 * }
	 * 
	 * 
	 * // 일반 값 받아 올때 (Xml Data, String Data);
	 * sendLoader.sendAndLoad('http://www.xxx.com/getListXml.php');
	 * 
	 * // get 방식
	 * sendLoader.sendAndLoad('http://www.xxx.com?name=park&age:28',null,'idx3');
	 * sendLoader.sendAndLoad('http://www.xxx.com',{name:'Park',age:28},'idx3');
	 * sendLoader.sendAndLoad('http://www.xxx.com',{name:'Park',age:28},'idx3','GET');
	 * 
	 * // post 방식
	 * sendLoader.sendAndLoad('http://www.xxx.com',{name:'Park',age:28},null,'POST');
	 * sendLoader.sendAndLoad('http://www.xxx.com',{name:'Park',age:28},'idx3','POST');
	 * 
	 * // XML 패킷을 보낼 시
	 * var xmlData:XML = <user>
	 * 						<name> park </name>
	 * 						<id>goldhwan</id>
	 * 					 </user>
	 * sendLoader.sendAndLoad('http://www.xxx.com',xmlData,'idx3','POST');
	 * 
	 * // ByteArray 로 보낼 시
	 * var byteArray:ByteArray = new ByteArray();
	 * sendLoader.sendAndLoad('http://www.xxx.com',byteArrData,'idx3','POST');
	 * 
	 */
	 
	public class SendLoadManager extends EventDispatcher
	{
		private var loaderDic:Dictionary;
		private var idxDic:Dictionary;
		
		public function SendLoadManager():void{}
		
		public function init():void
		{
			loaderDic 	= new Dictionary();
			idxDic 		= new Dictionary();
		}
		
		public function sendAndLoad(_urlStr:String,_paramObj:Object=null,_loadIdx:Object=null,_method:String='GET',_conType:String=null):void
		{
			var urlRequest:URLRequest 	= new URLRequest(_urlStr);
			var urlLoader:URLLoader 	= new URLLoader();
			
			if(_paramObj!=null){
				if(_paramObj is XML){
					urlRequest.data 		= _paramObj.toXMLString();
					urlRequest.contentType 	= 'text/xml';
				}else if(_paramObj is ByteArray){
					urlRequest.data 		= _paramObj;
					urlRequest.contentType 	= 'application/octet-stream';
				}else{
					urlRequest.data 		= setVars(_paramObj);
					urlRequest.contentType 	= _conType;
				}
			}
			
			if(_method=='POST') urlRequest.method 		= URLRequestMethod.POST;
			
			setListener(urlLoader);
			idxDic[urlLoader]	= _loadIdx;
			loaderDic[_loadIdx] = urlLoader;
			urlLoader.load(urlRequest);
		}
		
		// 보낼 값 있을 때 URLVarialbes 에 넣어서 리턴
		private function setVars(_obj:Object):URLVariables
		{
			var urlVars:URLVariables = new URLVariables();
			for(var prop in _obj){
				urlVars[prop] = _obj[prop];
			}		
			return urlVars;
		}
		
		// 이벤트 핸들러, dictionary 제거
		private function remove(_urlLoader:URLLoader):void
		{			
			var idx:Object = idxDic[_urlLoader];
			removeListener(_urlLoader);
			delete loaderDic[idx];
			delete idxDic[_urlLoader];			
		}
		
		// 외부에서 idx값으로 이벤트 핸들러, dictionary 제거
		public function removeLoader(_idx:Object):void
		{
			var urlLoader:URLLoader = loaderDic[_idx];
			removeListener(urlLoader);
			delete idxDic[urlLoader];
			delete loaderDic[_idx];
		}
		
		/*
		 *  각 이벤트 핸들러 등록 및 제거 
		 */
		private function setListener(_urlLoader:URLLoader):void
		{
			_urlLoader.addEventListener(Event.COMPLETE,completeHandler);
			_urlLoader.addEventListener(ProgressEvent.PROGRESS,progressHandler);
			_urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
            _urlLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
            _urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);	
		}
		private function removeListener(_urlLoader:URLLoader):void
		{
			_urlLoader.removeEventListener(Event.COMPLETE,completeHandler);
			_urlLoader.removeEventListener(ProgressEvent.PROGRESS,progressHandler);
			_urlLoader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
            _urlLoader.removeEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
            _urlLoader.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);	
		}
		private function completeHandler(_e:Event):void
		{
			var urlLoader:URLLoader = URLLoader(_e.target);
			var idx:Object 			= idxDic[urlLoader];
			var result:String 		= urlLoader.data;
			remove(urlLoader);
			dispatchEvent(new LoaderEvent(LoaderEvent.LOAD_COMPLETE,{evnt:_e,result:result,idx:idx}));
		}
		private function progressHandler(_e:ProgressEvent):void
		{
			var idx:Object = idxDic[_e.target];
			dispatchEvent(new LoaderEvent(LoaderEvent.LOAD_PROGRESS,{idx:idx, loaded:_e.bytesLoaded, total:_e.bytesTotal}));
		}
		private function securityErrorHandler(_e:SecurityErrorEvent):void 
		{
			dispatchEvent(new LoaderEvent(LoaderEvent.SECURITY_ERROR,{evnt:_e}));
        }
        private function httpStatusHandler(_e:HTTPStatusEvent):void 
		{
			dispatchEvent(new LoaderEvent(LoaderEvent.HTTP_STATUS,{evnt:_e}));
        }
        private function ioErrorHandler(_e:IOErrorEvent):void 
		{
			dispatchEvent(new LoaderEvent(LoaderEvent.IO_ERROR,{evnt:_e}));
        }
	}
}